package org.boot.fast.util;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.boot.fast.properties.FastSystemProperties;
import org.boot.fast.util.spring.SpringUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;

import static org.boot.fast.properties.FastSystemProperties.getProperties;

@Slf4j
public class FastQueryWrapperBuilder<T> {
//    private final Class<T> entityClass;
    private final Set<String> allFieldNames;
    private final Set<String> allDBFieldNames;

    public FastQueryWrapperBuilder(Class<T> entityClass) {
//        this.entityClass = entityClass;
        this.allFieldNames = getAllFieldNamesIncludingSuperclass(entityClass);
        this.allDBFieldNames = getDbFieldNames();
    }

    private static FastSystemProperties properties;

    /**
     * 获取类及其所有父类的字段名（直到Object类）
     */
    private Set<String> getAllFieldNamesIncludingSuperclass(Class<?> clazz) {
        Set<String> fieldNames = new HashSet<>();
        Class<?> currentClass = clazz;

        while (currentClass != null && currentClass != Object.class) {
            Field[] fields = currentClass.getDeclaredFields();
            for (Field field : fields) {
                // 跳过静态字段
                if (!Modifier.isStatic(field.getModifiers())) {
                    fieldNames.add(field.getName());
                }
            }
            currentClass = currentClass.getSuperclass();
        }

        return fieldNames;
    }

    /**
     * 构建查询条件（支持操作符后缀）
     * 格式：字段名@操作符，例如：name@like, age@gt, create_time@ge, id@sort
     * 默认操作符为 eq
     * 排序格式：字段名@sort=asc/desc
     */
    public QueryWrapper<T> buildQueryWrapper(Map<String, Object> queryParams) {
        return buildQueryWrapper(camelCaseMap(queryParams), true);
    }
    private Map<String, Object> camelCaseMap(Map<String, Object> params) {
        properties = getProperties();
        if (properties.getBatis().isCamelCase() && CollUtil.isNotEmpty(params)) {
            return MappingUtil.camelCaseMap(params);
        }
        return params;
    }

    /**
     * 构建查询条件
     * @param queryParams 查询参数
     * @param enableOperator 是否启用操作符后缀
     */
    public QueryWrapper<T> buildQueryWrapper(Map<String, Object> queryParams, boolean enableOperator) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        if (CollUtil.isEmpty(queryParams)) {
            return queryWrapper;
        }

        for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            if (isBlankValue(value)) {
                continue;
            }

            if (enableOperator && key.contains("@")) {
                // 解析操作符后缀 - 格式：字段名@操作符
                String[] parts = key.split("@", 2);
                if (parts.length == 2 && allDBFieldNames.contains(parts[0])) {
                    String field = parts[0];
                    String operator = parts[1];

                    // 特殊处理排序操作符
                    if ("sort".equalsIgnoreCase(operator)) {
                        handleSorting(queryWrapper, field, value.toString());
                    } else {
                        // 其他查询操作符
                        applyOperator(queryWrapper, operator, field, value);
                    }
                }
            }
//            else {
//                queryWrapper.eq(key, value);
//            }
            else if (allDBFieldNames.contains(key)) {
                // 默认等于查询
                queryWrapper.eq(key, value);
            }
        }
        return queryWrapper;
    }

    /**
     * 处理排序操作符   参数传递规则：&字段@sort=desc
     * @param field 字段名
     * @param order 排序方式
     */
    private void handleSorting(QueryWrapper<T> wrapper, String field, String order) {
        if ("desc".equalsIgnoreCase(order)) {
            wrapper.orderByDesc(field);
        } else {
            wrapper.orderByAsc(field);
        }
    }

    /**
     * 应用操作符
     */
    private void applyOperator(QueryWrapper<T> wrapper, String operator, String field, Object value) {
        switch (operator.toLowerCase()) {
            case "eq":
                wrapper.eq(field, value);
                break;
            case "like":
                wrapper.like(field, value);
                break;
            case "likeleft":
                wrapper.likeLeft(field, value);
                break;
            case "likeright":
                wrapper.likeRight(field, value);
                break;
            case "ne":
                wrapper.ne(field, value);
                break;
            case "gt":
                wrapper.gt(field, value);
                break;
            case "ge":
                wrapper.ge(field, value);
                break;
            case "lt":
                wrapper.lt(field, value);
                break;
            case "le":
                wrapper.le(field, value);
                break;
            case "in":
                if (value instanceof Iterable) {
                    wrapper.in(field, (Iterable<?>) value);
                } else if (value instanceof Object[]) {
                    wrapper.in(field, (Object[]) value);
                } else if (value instanceof String) {
                    // 支持逗号分隔的字符串
                    String[] values = ((String) value).split(",");
                    if (values.length > 0) {
                        wrapper.in(field, (Object[]) values);
                    }
                }
                break;
            case "notin":
                if (value instanceof Iterable) {
                    wrapper.notIn(field, (Iterable<?>) value);
                } else if (value instanceof Object[]) {
                    wrapper.notIn(field, (Object[]) value);
                } else if (value instanceof String) {
                    String[] values = ((String) value).split(",");
                    if (values.length > 0) {
                        wrapper.notIn(field, (Object[]) values);
                    }
                }
                break;
            case "isnull":
                wrapper.isNull(field);
                break;
            case "isnotnull":
                wrapper.isNotNull(field);
                break;
            case "between":
                // 支持范围查询，value 应该是包含两个元素的数组或列表
                if (value instanceof Object[] && ((Object[]) value).length == 2) {
                    Object[] range = (Object[]) value;
                    wrapper.between(field, range[0], range[1]);
                } else if (value instanceof List && ((List<?>) value).size() == 2) {
                    List<?> range = (List<?>) value;
                    wrapper.between(field, range.get(0), range.get(1));
                } else if (value instanceof String) {
                    // 支持字符串格式 "value1,value2"
                    String[] range = ((String) value).split(",");
                    if (range.length == 2) {
                        wrapper.between(field, range[0], range[1]);
                    }
                }
                break;
            default:
                wrapper.eq(field, value); // 默认等于查询
        }
    }

    /**
     * 判断是否为空值
     */
    private boolean isBlankValue(Object value) {
        if (value == null) {
            return true;
        }
        if (value instanceof String) {
            return StringUtils.isBlank((String) value);
        }
        return false;
    }

    /**
     * 获取所有字段名（包括父类） - 用于调试或其他用途
     */
    public Set<String> getFieldNames() {
        return new HashSet<>(allFieldNames);
    }

    public Set<String> getDbFieldNames() {
        HashSet<String> strings = new HashSet<>(allFieldNames);
        if (CollUtil.isEmpty(strings)) return Collections.emptySet();
        HashSet<String> result = new HashSet<>();
        for (String string : strings) {
            result.add(MappingUtil.mappingToTable(string));
        }
        return result;
    }

    /**
     * 静态工厂方法
     */
    public static <T> FastQueryWrapperBuilder<T> of(Class<T> entityClass) {
        return new FastQueryWrapperBuilder<>(entityClass);
    }
}
